package com.shihb.chapter04collection

/**
 * Description:集合map映射操作
 *
 * @author shihb
 * @date 2020/9/29 21:22
 */
object Demo07CollectionOperation {
  def main(args: Array[String]): Unit = {
    /*
    需求将List(3,5,7)元素*2生成新的集合
     */
    /*
      1、传统方式
      优点：简单易理解
      缺点：不够简洁高效,
            没体现函数式编程，
            不利于处理复杂的数据处理业务
     */
    //    test
    // 高阶函数
    val d: Double = test1(toDouble _, 3.5)
    println(d)
    //在scala把一个函数赋给一个变量而不是去执行
    val f1=test _
    f1()
    //map实现
    println("===map实现===")
    test2
    println("===flatMap===")
    test3
    println("===filter===")
    test4
    println("===reduce demo===")
    test5
    println("===fold demo===")
    test6
    println("===scan demo===")
    test7
    println("===zip demo===")
    test8
    println("===并行计算 demo===")
    test9
  }

  // 传统方法
  def test: Unit = {
    val list = List(3, 5, 7)
    var list2 = List[Int]()
    list.foreach(e => list2 = list2 :+ 2 * e)
    println(list2)

  }

  /*
    高阶函数
    f:Double=>Double表示一个函数,接收一个Double,返回一个Double
    n1:Double 普通参数
     f(n1)在test1中执行你传入的函数
   */
  def test1(f: Double => Double, n1: Double) = {
    f(n1)
  }

  //普通函数
  def toDouble(d: Double): Double = {
    println("toDouble被调用")
    d * 2
  }
  //map实现
  def test2: Unit ={
    val list = List(3.0, 5.0, 7.0)
    /*  1 遍历map的各个元素
        2 执行toDouble方法的,得到新的值
        3 将所有返回封装成一个List返回
     */
    val list1: List[Double] = list.map(toDouble)
    println(list1)
  }
  // 扁平化输出flatMap
  def test3: Unit ={

    val list = List("shb", "love", "cl")
    println(list.flatMap(e => e.toUpperCase))
  }

  // 过滤filter true的留下来,false被过滤了
  def test4: Unit ={
    val list = List("shb", "love", "cl")
    val list1: List[String] = list.filter(e => !"love".equalsIgnoreCase(e))
    println(list1)
  }
  //reduce化简
  def test5: Unit ={
    val list = List(1,2,3,4,9,5,6,7,8)
    // reduceLeft 从左边执行 (1+2)+3)+4+5+6...
    val result: Int = list.reduceLeft((o1, o2) => o1 + o2)
    println(result)
    val list2 = List(2.0,2.0,4.0)
    // reduceRight 2/(2/4) 不是4/2/2 要注意
    val d: Double = list2.reduceRight((o1, o2) => o1 / o2)
    println(d)
    // reduce 等价于 reduceLeft
    println(list2.reduce((o1, o2) => o1 / o2))
    println(list2.reduceLeft((o1, o2) => o1 / o2))


    println(list.reduce((o1, o2) => math.max(o1, o2)))
  }
  // 折叠
  def test6: Unit ={
    val list = List(2.0,2.0,4.0)
    // 函数的柯里化
    // 左折叠和折叠等价
    val a: Double = list.fold(8.0)((o1, o2) => o1 - o2)
    //简写
    val a3:Double =list.fold(8.0)(_-_)

    // 左折叠缩写
    val a2: Double = (8.0 /: list) ((o1, o2) => o1 - o2)
    // 相当于 如下
    val b: Double = (8.0 +: list).reduceLeft((o1, o2) => o1 - o2)
    println(a,a2,a3,b)

    // 右折叠
    val c: Double = list.foldRight(1.0)((o1, o2) => o1 / o2)
    // 右折叠缩写
    val c1: Double = (list :\ 1.0) ((o1, o2) => o1 / o2)

    val d: Double =(list:+1.0).reduceRight((o1, o2) => o1 / o2)
    println(c,c1,d)

  }
  // 扫描 和fold一个逻辑只是记录每个过程
  def test7: Unit ={
    val list = List(2.0,2.0,4.0)
    val list1: List[Double] = list.scan(8.0)((o1, o2) => o1 / o2)
    println(list1)//List(8.0, 4.0, 2.0, 0.5)
    val list2: List[Double] = list.scanRight(1.0)((o1, o2) => o1 / o2)
    println(list2)//List(4.0, 0.5, 4.0, 1.0)
  }
  // 拉链表,对偶元组
  def test8: Unit ={
    val list = List(1, 2, 3,4)
    val list1 = List("a", "b", "c")
    val tuples: List[(Int, String)] = list.zip(list1)
    //List((1,a), (2,b), (3,c))
    println(tuples)
  }
  // 并行计算
 def test9: Unit ={
   (1 to 5).foreach(println(_))
   println("=====")
   //集合加一个par 启动并行计算
   // 输出的结果无需,说明了将println任务分配给不同的cpu
   // 默认多少cup核心数用多少线程
   (1 to 5).par.foreach(println(_))


   println((1 to 10).map { case _ => Thread.currentThread.getName }.distinct)
   println("======")
   println((1 to 10).par.map { case _ => Thread.currentThread.getName }.distinct)

 }

}
